#include "raft/node.h"

int main() {
  libraft::Options options1(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8901, "data1", "meta1", "log1");
  libraft::RaftNode raft_node1(options1);
  std::shared_ptr<libraft::Raft> raft1 = raft_node1.StartNode("raft_example5/");

  libraft::Options options2(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8902, "data2", "meta2", "log2");
  libraft::RaftNode raft_node2(options2);
  std::shared_ptr<libraft::Raft> raft2 = raft_node2.StartNode("raft_example5/");

  libraft::Options options3(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8903, "data3", "meta3", "log3");
  libraft::RaftNode raft_node3(options3);
  std::shared_ptr<libraft::Raft> raft3 = raft_node3.StartNode("raft_example5/");

  std::string server_status;
  while (1) {
    if (raft1->HasLeader()) {
      raft1->GetServerStatus(&server_status);
      LOG_INFO << server_status;
      break;
    }

    LOG_INFO << "electing leader... sleep 2s";
    std::this_thread::sleep_for(std::chrono::seconds(2));
  }

  for (int i = 0; i < 1000; i++) {
    rocksdb::Status s = raft1->Write(std::to_string(i), std::to_string(i));
    std::string value;
    s = raft1->Read(std::to_string(i), &value);
  }

  libraft::Options options4(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8904, "data4", "meta4", "log4");
  libraft::RaftNode raft_node4(options4);
  std::shared_ptr<libraft::Raft> raft4 = raft_node4.StartNode("raft5_example/");
  raft1->AddPeer("127.0.0.1:8904");

  while (1) {
    LOG_INFO << "electing leader after server 4 join the cluster... sleep 2s";
    std::this_thread::sleep_for(std::chrono::seconds(2));
    if (raft1->HasLeader()) {
      raft1->GetServerStatus(&server_status);
      LOG_INFO << server_status;
      break;
    }
  }

  for (int i = 1000; i < 2000; i++) {
    rocksdb::Status s = raft1->Write(std::to_string(i), std::to_string(i));
    std::string value;
    s = raft1->Read(std::to_string(i), &value);
  }

  libraft::Options options5(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8905, "data5", "meta5", "log5");
  libraft::RaftNode raft_node5(options5);
  std::shared_ptr<libraft::Raft> raft5 = raft_node3.StartNode("raft5_example/");
  raft1->AddPeer("127.0.0.1:8905");

  while (1) {
    LOG_INFO << "electing leader after server 5 join the cluster... sleep 2s";
    std::this_thread::sleep_for(std::chrono::seconds(2));
    if (raft1->HasLeader()) {
      raft1->GetServerStatus(&server_status);
      LOG_INFO << server_status;
      break;
    }
  }
  return 0;
}